package zzzhc.image.recognize.filter;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import zzzhc.image.recognize.Filter;
import zzzhc.image.recognize.RecognizeContext;

public class ClearFilter implements Filter {

	private static final long serialVersionUID = 4805750120230114563L;

	private static final int LABEL_START = 300;

	private int threshold = 5;

	public int getThreshold() {
		return threshold;
	}

	public void setThreshold(int threshold) {
		this.threshold = threshold;
	}

	public void doFilter(RecognizeContext source) {
		int label = LABEL_START;
		Map<Integer, Integer> countMap = new HashMap<Integer, Integer>();
		for (int y = 0; y < source.getHeight(); y++) {
			for (int x = 0; x < source.getWidth(); x++) {
				if (source.getValue(x, y) == 1) {
					int oldLabel = source.getValue(x + 1, y - 1);
					if (oldLabel == 0) {
						oldLabel = source.getValue(x, y - 1);
					}
					if (oldLabel == 0) {
						oldLabel = source.getValue(x - 1, y - 1);
					}
					if (oldLabel == 0) {
						oldLabel = source.getValue(x - 1, y);
					}
					if (oldLabel == 0) {
						source.setValue(x, y, label);
						countMap.put(label, 1);
						label++;
					} else {
						source.setValue(x, y, oldLabel);
						countMap.put(oldLabel, countMap.get(oldLabel) + 1);
					}
				}
			}
		}

		for (int y = 0; y < source.getHeight(); y++) {
			for (int x = 0; x < source.getWidth(); x++) {
				int leftLabel = source.getValue(x - 1, y);
				int currentLabel = source.getValue(x, y);
				int leftTopLabel = source.getValue(x - 1, y - 1);
				if (currentLabel >= LABEL_START) {
					int mLabel = -1;
					if (leftLabel >= LABEL_START && leftLabel != currentLabel) {
						mLabel = leftLabel;
					} else if (leftLabel < LABEL_START
							&& leftTopLabel >= LABEL_START
							&& leftTopLabel != currentLabel) {
						mLabel = leftTopLabel;
					}
					if (mLabel >= LABEL_START) {
						int newLabel = label++;
						countMap.put(newLabel, countMap.get(mLabel)
								+ countMap.get(currentLabel));
						countMap.remove(mLabel);
						countMap.remove(currentLabel);
						reset(source, mLabel, currentLabel, newLabel);
					}
				}

			}
		}

		for (Iterator<Integer> ite = countMap.keySet().iterator(); ite
				.hasNext();) {
			Integer key = ite.next();
			if (countMap.get(key) <= threshold) {
				ite.remove();
			}
		}

		for (int y = 0; y < source.getHeight(); y++) {
			for (int x = 0; x < source.getWidth(); x++) {
				int value = source.getValue(x, y);
				if ((value >= LABEL_START) && (countMap.get(value) != null)) {
					source.setValue(x, y, 1);
				} else {
					source.setValue(x, y, 0);
				}
			}
		}

	}

	private void reset(RecognizeContext source, int label1, int label2,
			int newLabel) {
		for (int y = 0; y < source.getHeight(); y++) {
			for (int x = 0; x < source.getWidth(); x++) {
				int value = source.getValue(x, y);
				if (value == label1 || value == label2) {
					source.setValue(x, y, newLabel);
				}
			}
		}
	}

}
